package com.example.stock.api.impl;

import com.example.stock.api.StockApiService;
import com.example.stock.model.StockDailyData;
import com.example.stock.model.StockInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.ParseException;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * 新浪股票API实现类
 *
 * @author zwg
 * @date 2025/8/5 22:00
 */
@Service
@Slf4j
public class SinaStockApiServiceImpl implements StockApiService {

    @Autowired
    private CloseableHttpClient httpClient;

    @Value("${stock.api.sina.base-url}")
    private String sinaApiBaseUrl;

    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");


    /**
     * 根据股票代码获取股票基本信息
     *
     * @param code
     */
    @Override
    public StockInfo getStockInfo(String code) {
        // 构建请求URL
        String url = sinaApiBaseUrl + code;

        try {
            HttpGet httpGet = new HttpGet(url);
            try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    String result = EntityUtils.toString(entity, StandardCharsets.UTF_8);
                    return parseStockInfo(code, result);
                }
            }
        } catch (IOException | ParseException e) {
            log.error("获取股票信息失败: {}", e.getMessage());
        }

        return null;
    }

    /**
     * 获取股票某日的交易数据
     *
     * @param code
     * @param date
     */
    @Override
    public StockDailyData getStockDailyData(String code, LocalDate date) {
        // 新浪财经API获取单日数据的实现
        String url = String.format("http://money.finance.sina.com.cn/quotes_service/api/json_v2.php/CN_MarketData.getKLineData?" +
                        "symbol=%s&scale=240&ma=no&datalen=1&begin=%s",
                code, date.format(DATE_FORMATTER));

        try {
            HttpGet httpGet = new HttpGet(url);
            try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    String result = EntityUtils.toString(entity, StandardCharsets.UTF_8);
                    return parseStockDailyData(code, result);
                }
            }
        } catch (IOException | ParseException e) {
            log.error("获取股票每日数据失败: {}", e.getMessage());
        }

        return null;
    }

    /**
     * 获取股票一段时间内的交易数据
     *
     * @param code
     * @param startDate
     * @param endDate
     */
    @Override
    public List<StockDailyData> getStockHistoricalData(String code, LocalDate startDate, LocalDate endDate) {
        // 实现获取历史数据的逻辑
        List<StockDailyData> dataList = new ArrayList<>();

        // 这里简化实现，实际应根据日期范围分批获取
        LocalDate currentDate = startDate;
        while (!currentDate.isAfter(endDate)) {
            // 跳过周末
            if (currentDate.getDayOfWeek().getValue() < 6) {
                StockDailyData dailyData = getStockDailyData(code, currentDate);
                if (dailyData != null) {
                    dataList.add(dailyData);
                }
            }
            currentDate = currentDate.plusDays(1);
        }

        return dataList;
    }

    /**
     * 获取市场所有股票列表
     *
     * @param market
     */
    @Override
    public List<String> getAllStockCodes(String market) {
        // 实际应用中，这里应该从股票列表API获取所有股票代码
        // 这里返回一些示例代码
        List<String> codes = new ArrayList<>();
        if ("SH".equals(market)) {
            codes.add("sh600000"); // 浦发银行
            codes.add("sh600036"); // 招商银行
            codes.add("sh601318"); // 中国平安
        } else if ("SZ".equals(market)) {
            codes.add("sz000001"); // 平安银行
            codes.add("sz000858"); // 五 粮 液
            codes.add("sz002594"); // 比亚迪
        }
        return codes;
    }

    /**
     * 解析股票基本信息
     */
    private StockInfo parseStockInfo(String code, String response) {
        // 新浪股票API返回格式示例: var hq_str_sh600000="浦发银行,9.94,9.93,9.99,..."
        try {
            int startIndex = response.indexOf("\"");
            int endIndex = response.lastIndexOf("\"");
            if (startIndex > 0 && endIndex > startIndex) {
                String dataStr = response.substring(startIndex + 1, endIndex);
                String[] data = dataStr.split(",");

                StockInfo stock = new StockInfo();
                stock.setCode(code);
                stock.setName(data[0]);
                stock.setMarket(code.startsWith("sh") ? "SH" : "SZ");

                // 其他字段需要从更详细的接口获取，这里简化处理
                stock.setIndustry("未知");
                stock.setFullName(data[0]);
                stock.setListingDate("未知");

                return stock;
            }
        } catch (Exception e) {
            log.error("解析股票信息失败: {}", e.getMessage());
        }
        return null;
    }

    /**
     * 解析股票每日交易数据
     */
    private StockDailyData parseStockDailyData(String code, String response) {
        try {
            // 新浪K线数据格式示例: [{"day":"2023-11-10","open":"9.93","high":"10.04",...}]
            if (response.startsWith("[") && response.endsWith("]")) {
                String jsonData = response.substring(1, response.length() - 1);
                if (!jsonData.isEmpty()) {
                    // 简单解析，实际应用中应使用Jackson等JSON库
                    String day = extractValue(jsonData, "day");
                    String open = extractValue(jsonData, "open");
                    String close = extractValue(jsonData, "close");
                    String high = extractValue(jsonData, "high");
                    String low = extractValue(jsonData, "low");
                    String volume = extractValue(jsonData, "volume");
                    String amount = extractValue(jsonData, "amount");
                    String changePercent = extractValue(jsonData, "percent");

                    StockDailyData dailyData = new StockDailyData();
                    dailyData.setCode(code);
                    dailyData.setDate(LocalDate.parse(day, DATE_FORMATTER));
                    dailyData.setOpenPrice(new BigDecimal(open));
                    dailyData.setClosePrice(new BigDecimal(close));
                    dailyData.setHighPrice(new BigDecimal(high));
                    dailyData.setLowPrice(new BigDecimal(low));
                    dailyData.setVolume(Long.parseLong(volume));
                    dailyData.setAmount(new BigDecimal(amount));
                    dailyData.setChangePercent(new BigDecimal(changePercent));

                    return dailyData;
                }
            }
        } catch (Exception e) {
            log.error("解析股票每日数据失败: {}", e.getMessage());
        }
        return null;
    }

    /**
     * 简单提取JSON字段值
     */
    private String extractValue(String json, String key) {
        int index = json.indexOf("\"" + key + "\":\"");
        if (index == -1) {
            return "";
        }
        int start = index + key.length() + 3;
        int end = json.indexOf("\"", start);
        return end > start ? json.substring(start, end) : "";
    }
}
